package pl.edu.agh.ki.neuralnetwork.network;

import java.util.List;

import pl.edu.agh.ki.neuralnetwork.exceptions.OutOfRangeException;
import pl.edu.agh.ki.neuralnetwork.exceptions.ResultNotReadyException;
import pl.edu.agh.ki.neuralnetwork.layer.Layer;

public interface NeuralNetwork {
	/**
	 * Sets value for input neuron.
	 * 
	 * @param no
	 *            Neuron (input) number.
	 * @param val
	 *            Value
	 * @throws OutOfRangeException
	 */
	public void setInputSignal(int no, double val) throws OutOfRangeException;

	/**
	 * Sets values for input neurons.
	 * 
	 * @param s
	 *            Table containing input values.
	 */
	public void setInputSignals(Double s[]);

	/**
	 * Computes outcome of a neural network.
	 */
	public void compute();

	/**
	 * Return output values from last layer
	 * 
	 * @return output values
	 * @throws ResultNotReadyException
	 */
	public Double[] getOutputSignals() throws ResultNotReadyException;

	/**
	 * Return output value from a neuron in last layer.
	 * 
	 * @param no
	 *            Neuron number
	 * @return output value
	 * @throws OutOfRangeException
	 * @throws ResultNotReadyException
	 */
	public Double getOutputSignal(int no) throws OutOfRangeException,
			ResultNotReadyException;

	/**
	 * @return last layer size
	 */
	public int getOutputSize();

	/**
	 * @return input layer size
	 */
	public int getInputSize();

	/**
	 * @param no
	 *            layer number
	 * @return Neurons list from exact layer
	 * @throws OutOfRangeException
	 */
	public Layer getLayer(int no) throws OutOfRangeException;

	/**
	 * @return Number of layers
	 */
	public int getLayersNumber();

	/**
	 * Resets outputs from all neurons in network
	 */
	public void resetOutput();

	/**
	 * it modify weights of the network in order to learn it
	 * 
	 * @param learningInput
	 * @param pattern
	 * @param iteration
	 */
	public void learn(List<Double> learningInput, List<Double> pattern,
			int iteration);
}